package controllers

import play._
import play.mvc._

import models._
import dao._

object User extends Controller with Secure {
  import views.User._
  import config.Services._
  import java.io.File
  
  def details(fullname:String, det:models.User.Details) = {
    play.Logger.info("details received")
     using(dbSession){ s =>
        UserDAO.findByName(session("username").get) match {
          case Some(u:models.User)    => {
            u.det = Some(det)
            u.fullname = fullname
            u.update()
            Text("OK")
          }
          case None                   => Text("ERROR")
        }
     }
  }
  
  def getPreferences = {
    if(isLogedIn){
      models.User.Preferences( session("userfont").get.toByte, session("usertheme").get )
    } else {
      models.User.getDefaultPreferences
    }
  }
  
  def panel = {
    html.panel( session("username"), getPreferences )
  }
  
  def settings = {
    html.settings(session("username"), getPreferences)
  }
  
  def saveSettings(pref:models.User.Preferences) = {
    using(dbSession){ s =>
      UserDAO.findByName(session("username").get) match {
        case Some(u:models.User)  => {
          // si existe un obeto Preferences, actualizar. Si no, asignar.
          u.pref match {
            case Some(p) => u.pref.get.fontSize = pref.fontSize; u.pref.get.themeName = pref.themeName
            case None => u.pref = Some(pref)
          }
          u.update()
          
          Text("OK")
        }
        case None                 => Text("ERROR: User nor found.")
      }
    }
  }
  
  def perfil = {
    using(dbSession){ s =>
      
      UserDAO.findByName(session("username").get) match {
        case Some(user)     => html.perfil(user, getPreferences, user.posts)
        case None           => Unauthorized
      } //match
    
    } //db
  }
  
  def avatarForm = {
    html.avatar()
  }
  
  def avatarUpload(avatar:Option[File]) = {
    avatar match {
      case Some(file)     => {
        var ext = ""
        if(file.getName().endsWith("jpg") || file.getName().endsWith("jpeg")){
          ext = "jpg"
        } else if(file.getName().endsWith("gif")){
          ext = "gif"
        } else if(file.getName().endsWith("png")){
          ext = "gif"
        }
        
        if(!ext.isEmpty){
          val now = new java.util.Date()
          var dest = new java.io.File(
                concretePath(avatarsPath), session("username").get +
                "_" + now.getTime() + 
                "." + ext
              )
          var destThumb = new java.io.File(
                concretePath(avatarsThumbPath), session("username").get +
                "_" + now.getTime() + 
                "." + ext
              )
            
          try{
            //play.libs.Files.copy(file, dest)
            play.libs.Images.resize(file, destThumb, defaultThumbWidth, -1)
            //play.libs.Images.resize(destThumb, destThumb, -1, config.Services.defaultThumbWidth)
            
            play.libs.Images.resize(file, dest, defaultAvatarWidth, -1)
            //play.libs.Images.resize(dest, dest, -1, config.Services.defaultAvatarWidth)
            
            using(dbSession){ s =>
              UserDAO.findByName(session("username").get) match {
                case Some(u:models.User)       => {
                  play.libs.Files.delete( new java.io.File(concretePath(avatarsPath) + u.photo) )
                  play.libs.Files.delete( new java.io.File(concretePath(avatarsThumbPath) + u.photo) )
                  u.photo = dest.getName()
                  u.update()
                  <script>
                    parent.$('#profile-avatar-edit').attr('src', {"'" + avatarsPath + u.photo +"'"});
                    parent.$.fancybox.close();
                  </script>
                }
                case None             => Unauthorized
              }
            }
          
          }
        } else {
          <p>
          <strong>Formato incompatible</strong><br />
          La imagen seleccionada no puede ser usada en su perfil. <br />
          Escoja archivos <em>jpeg, gif o png</em>
          <a href="/user/avatar">Intentar con otra imagen</a>
        </p>
        }
      }
      
      case None           => {
        <p>
          <strong>Se mantendrá su imagen actual</strong><br />
          No ha escogido una imagen para usar en su perfil.
          <a href="javascript:parent.$.fancybox.close();">Continuar</a>
        </p>
      }
    }
  }
  
  def logout = {
    session.clear()
    Redirect("/")
  }
  
  def publish(cat:Byte = 0, year:Short=0, lat:Long=0, lng:Long=0, sticky:Boolean = false) = {
    html.publish(cat, year, lat, lng, sticky)
  }
  
  def edit(pid:Long) = {
    using(dbSession){ s =>
      html.publish(p=PostDAO.findByID(pid))
    }
  }
  
  def editSubmit(pid:Long, title:String, content:String, category:Byte, year:Short, attachment:Option[File]) = {
    using(dbSession){ s =>
      PostDAO.findByID(pid) match {
        case Some(p) => {
          
          p.title = title
          p.content = content
          p.category = Post.Category(category)
          p.year = year
          
          if(attachment.isDefined){
            p.resource = createMedia(attachment)
          }
          
          p.update()
          
          publishSuccess(false, p.id)
        }
        case None => Unauthorized
      }
    }
  }
  
  def publishSuccess(sticky:Boolean, pid:Long) = {
    html.publishSuccess(sticky, pid)
  }
  
  def publishSubmit(title:String, content:String, category:Byte, year:Short, lat:Long, lng:Long, attachment:Option[File], sticky:Boolean) = {
    val loc = Post.Location(lat, lng)
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get) match {
        case Some(u) => {
          val p = u.publish(title, content, year, loc, createMedia(attachment), Post.Category(category) )
          publishSuccess(sticky, p.get.id) //XXX
        }
        case None => Unauthorized
      }
    }
  }
  
  private def createMedia(attachment:Option[File]):Post.Media = {
    val now = new java.util.Date()
    val ext = attachment.map( _.getName.split('.').last.toLowerCase ).getOrElse("") //extensión
    val filename = session("username").get + "_" + now.getTime + "." + ext
    var media = Post.Media(MediaKind.NONE, "")
    
    if(ext.isEmpty){ //tanto si no se subió archivo como si no posee extensión
    
      Post.Media(MediaKind.NONE, "")
    
    } else {
      
      if(Vector("jpg","jpeg","gif","png") contains ext){
        val destFull = new File( concretePath(imagesPath), filename )
        val destThumb = new File( concretePath(resizedImagesPath), filename )
    
        try{
          //copiar imagen real
          play.libs.Files.copy(attachment.get, destFull)
          //crear redimensión
          play.libs.Images.resize(attachment.get, destThumb, defaultImageWidth, -1)
          //crear objeto Post.Media
          Post.Media(MediaKind.IMAGE, resizedImagesPath + filename)
        }
        
      } else if(Vector("mp3","aac","oga","ogg", "wav") contains ext){
        val destFull = new File( concretePath(soundsPath), filename )
        
        try{
          //copiar
          play.libs.Files.copy(attachment.get, destFull)
          Post.Media(MediaKind.SOUND, soundsPath + filename)
        }
        
      } else if(Vector("mp4", "flv", "webm", "ogv") contains ext){
        val destFull = new File( concretePath(videosPath), filename )
        
        try{
          //copiar
          play.libs.Files.copy(attachment.get, destFull)
          Post.Media(MediaKind.VIDEO, videosPath + filename)
        }
      } else { //XXX
    
        Post.Media(MediaKind.NONE, "")
    
      }
    }
  }
  
  def commentSubmit(content:String, pid:Long) = {
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get) match {
        case Some(u) => {
            PostDAO.findByID(pid) match {
              case Some (p) => u.comment(content, p); Text("OK")
              case None     => Text("ERROR: La publicacion no existe")
            }
        }
        case None => Unauthorized
      }
    }
  }
  
  def messageSubmit(title:String, content:String, username:String) = {
    using(dbSession){ s=>
      UserDAO.findByName( session("username").get ) match {
        case Some(sender) => {
          UserDAO.findByName(username) match {
            case Some(target) => sender.sendMessage(target, title, content); Text("OK")
            case None         => Text("ERROR: El destinatario no existe")
          }
        }
        case None             => Unauthorized
      }
    }
  }
  
  def fave(pid:Long) = {
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get ) match {
        case Some(u) => {
          PostDAO.findByID(pid).map { p => u.fave(p); Text("OK") } getOrElse ("ERROR: La publicación no existe")
        }
        case None   => Text("ERROR: Usuario no existe") 
      }
    }
  }
  
  def unfave(pid:Long) = {
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get ) match {
        case Some(u) => {
          PostDAO.findByID(pid).map { p => u.unfave(p); Text("OK") } getOrElse ("ERROR: La publicación no existe")
        }
        case None   => Text("ERROR: Usuario no existe") 
      }
    }
  }
  
  def follow(username:String) = {
    play.Logger.info(username)
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get ) match {
        case Some(u) => {
          UserDAO.findByName(username).map { f => u.follow(f); Text("OK") } getOrElse ("ERROR: Usuario no existe")
        }
        case None   => Text("ERROR: Usuario no existe") 
      }
    }
  }
  
  def unfollow(username:String) = {
    using(dbSession){ s =>
      UserDAO.findByName( session("username").get ) match {
        case Some(u) => {
          UserDAO.findByName(username).map { f => u.unfollow(f); Text("OK") } getOrElse ("ERROR: Usuario no existe")
        }
        case None   => Text("ERROR: Usuario no existe") 
      }
    }
  }

}
